/**
 * Project Reactor
 */


#include "TcpConnection.h"
#include "EventLoop.h"
#include <string.h>
#include <sstream>
#include <iostream>
using std::endl;
using std::cout;
using std::ostringstream;
/**
 * TcpConnection implementation
 */


TcpConnection::TcpConnection(int fd, EventLoop * p) 
:_sock(fd)
,_socketIO(fd)
,_localAddr(getLocalAddr())
,_peerAddr(getPeerAddr())
,_isShutDown(false)
,_eventLoop(p)
{

}
TcpConnection::~TcpConnection()
{
    if(_isShutDown)
    {
        shutdown();
    }
}

/**
 * @return string
 */
string TcpConnection::recv() {
    char buf[65536];
    memset(buf, 0, sizeof(buf));
    _socketIO.readline(buf,sizeof(buf));
    return string(buf);
}


/**
 * @param msg
 */
void TcpConnection::send(const string msg) {
    cout << "TcpConnection.cpp 51 send(), send msg : " << msg << endl;
    _socketIO.sendn(msg.c_str(), msg.size());

}

/**
 * @return InetAddress
 */
InetAddress TcpConnection::getLocalAddr() {
    struct sockaddr_in addr ;
    socklen_t len = sizeof(struct sockaddr);
    if(getsockname(_sock.fd(), (struct sockaddr*)&addr, &len)< 0)
        perror("getsockname");
    return InetAddress(addr);
}

/**
 * @return InetAddress
 */
InetAddress TcpConnection::getPeerAddr() {
    struct sockaddr_in addr ;
    socklen_t len = sizeof(struct sockaddr);
    if(getpeername(_sock.fd(), (struct sockaddr*)&addr, &len)< 0)
        perror("getsockname");
    return InetAddress(addr);
}

string TcpConnection::toString()
{
    ostringstream ss;
    ss << "peerAddr = " << _peerAddr.getip() << "peerPort = " << _peerAddr.getport();
    return ss.str();

}

bool TcpConnection::isClosed()
{
    return _socketIO.recvPeek() == 0;
}

void TcpConnection::setAllCallbacks(Callback  &Close, Callback& Msg, Callback &On)
{
    _onClose = Close;
    _onMessage = Msg;
    _onConnection = On;
}

void TcpConnection::handleCloseCallback()
{
    if(_onClose)
    {
        _onClose(shared_from_this());
    }
}

void TcpConnection::handleMessageCallback()
{
        // cout << "TcpConnection.cpp 108 handleMessageCallback(), in handleMessageCallback" << endl;
    if(_onMessage)
    {
        // cout << "TcpConnection.cpp 111 handleMessageCallback(),in handleMessageCallback" << endl;
        _onMessage(shared_from_this());
    }
}

void TcpConnection::handleConnectionCallback()
{
    if(_onConnection)
    {
        _onConnection(shared_from_this());
    }
}


void TcpConnection::sendtoLoop(const string msg)
{
    if(_eventLoop)
    {
        _eventLoop->runInLoop(std::bind(&TcpConnection::send,this,msg));
    }
}

void TcpConnection::shutdown()
{
    if(!_isShutDown)
    {
        _isShutDown = true;
        _sock.shutDownWrite();
    }

}









